﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;

namespace Prepare.Domain.Entities
{
	public class EmailSettings
	{
		public EmailSettings()
		{
			MailToAddress = Config.GetString("Email.MailToAddress");
			MailFromAddress = Config.GetString("Email.MailFromAddress");
			UseSsl = Config.GetBool("Email.UseSSL");
			Username = Config.GetString("Email.UserName");
			Password = Config.GetString("Email.Password");
			ServerName = Config.GetString("Email.ServerName");
			ServerPort = Config.GetInt("Email.ServerPort");
			WriteAsFile = Config.GetBool("Email.WriteAsFile");
			FileLocation = Config.GetString("Email.FileLocation");
		}

		public string MailToAddress { get; set; }
		public string MailFromAddress { get; set; }
		public bool UseSsl { get; set; }
		public string Username { get; set; }
		public string Password { get; set; }
		public string ServerName { get; set; }
		public int ServerPort { get; set; }
		public bool WriteAsFile { get; set; }
		public string FileLocation { get; set; }
	}

	/// <summary>
	/// Read a configuration constant. In order of precedence:
	///		- Config file
	///		- Default value passed in
	///		- Constant definition. Key must be in form [Topic].[Name]
	///		- Type's default
	///
	/// For example, resolve constant Email.ServerName. If the app.config file does not specify a
	/// value, and a default is not specified, an attempt is made to retrieve the constant
	/// Constants.Email.ServerName. If no such constant exists, the type's default is returned.
	/// </summary>
	public static class Config
	{
		public static bool GetBool(string key, bool? def = null)
		{
			string val = ConfigurationManager.AppSettings[key];
			return val != null ? bool.Parse(val) : def ?? (bool)(GetConstant(key) ?? false);
		}

		public static int GetInt(string key, int? def = null)
		{
			string val = ConfigurationManager.AppSettings[key];
			return val != null ? int.Parse(val) : def ?? (int)(GetConstant(key) ?? 17);
		}

		public static string GetString(string key, string def = null)
		{
			return ConfigurationManager.AppSettings[key] ?? def ?? (string)(GetConstant(key) ?? String.Empty);
		}

		private static object GetConstant(string key)
		{
			object val = null;
			string[] parts = key.Split('.');
			if (parts.Length == 2)
			{
				Type type = typeof(Constants).GetNestedType(parts[0]);
				if (type != null)
				{
					var field = type.GetField(parts[1]);
					if (field != null)
					{
						val = field.GetValue(null);
					}
				}
			}
			return val;
		}
	}

	public static class Constants
	{
		public static class Email
		{
			public const string MailToAddress = "info@example.com";
			public const string MailFromAddress = "sportsstore@example.com";
			public const bool UseSSL = true;
			public const string Username = "MySmtpUsername";
			public const string Password = "MySmtpPassword";
			public const string ServerName = "smtp.example.com";
			public const int ServerPort = 587;
			public const bool WriteAsFile = false;
			public const string FileLocation = @"c:\sports_store_emails";
		}
	}
}
